﻿using LitJson;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace FrameWorkSong
{
    public class PrefabsCreate
    {
    
        SimpleObjectPool<BasePrefabs> Pool;
        Transform PrefabsFa;
        Dictionary<string, BasePrefabs> DictPrefabsBase = new Dictionary<string, BasePrefabs>();
        bool ISUI = false;
    
        /// <summary>
        /// 构造预制体创建
        /// </summary>
        /// <param name="prefabsType"></param>
        /// <param name="isUI"></param>
        /// <param name="Fa"></param>
        public PrefabsCreate(PrefabsType prefabsType, bool isUI, Transform Fa)
        {
            ISUI = isUI;
            if (Fa == null)
            {
                PrefabsFa = new GameObject(prefabsType.ToString()).transform;
                if (isUI)
                {
                    PrefabsFa.SetParent(UIManager.CanvasTransform);
                }
            }
            else
            {
                PrefabsFa = Fa;
            }

            Pool = new SimpleObjectPool<BasePrefabs>(() => getBasePrefabs(prefabsType), RecycleBasePrefabs, 0);
        }
        /// <summary>
        /// 实例预制体
        /// </summary>
        /// <param name="prefabsVec">预制体位置字典</param>
        public void Add(Dictionary<string, Vector3> prefabsVec)
        {
            foreach (var item in prefabsVec)
            {
                Add(item.Key, item.Value);

            }
        }
        /// <summary>
        /// 实例预制体
        /// </summary>
        /// <param name="name">预制体名称</param>
        /// <param name="vector3">预制体位置</param>
        public void Add(string name, Vector3 vector3)
        {

            BasePrefabs mBasePrefabs;
            if (!DictPrefabsBase.ContainsKey(name))
            {
                mBasePrefabs = Pool.Allocate();
                DictPrefabsBase.Add(name, mBasePrefabs);
            }
            else
            {
                mBasePrefabs = DictPrefabsBase[name];
            }

            if (!ISUI)
            {
                mBasePrefabs.SetPos(vector3);
            }
            else
            {
                mBasePrefabs.SetUIPos(vector3);
            }
            mBasePrefabs.SetName(name);

            mBasePrefabs.OnEnter();

            mBasePrefabs.Show();//显示预制体

        }
        /// <summary>
        /// 清除预制体实例
        /// </summary>
        /// <param name="names">清除预制体名称表</param>
        public void Remove(List<string> names)
        {
            for (int i = 0; i < names.Count; i++)
            {
                Remove(names[i]);
            }
        }
        /// <summary>
        /// 清除预制体实例
        /// </summary>
        /// <param name="name">清除预制体名称</param>
        public void Remove(string name)
        {
            BasePrefabs mBasePrefabs = DictPrefabsBase[name];
            mBasePrefabs.OnExit();
            mBasePrefabs.Hidden();//隐藏预制体
            Pool.Recycle(mBasePrefabs);
            DictPrefabsBase.Remove(name);
        }
        /// <summary>
        /// 清除全部预制体实例
        /// </summary>
        public void Remove()
        {
            foreach (var item in DictPrefabsBase)
            {
                BasePrefabs mBasePrefabs = item.Value;
                mBasePrefabs.OnExit();
                mBasePrefabs.Hidden();//隐藏预制体
                Pool.Recycle(mBasePrefabs);
            }
            DictPrefabsBase.Clear();
        }

        /// <summary>
        /// 得到预制体控制脚本
        /// </summary>
        /// <param name="prefabsType"></param>
        /// <returns></returns>
        BasePrefabs getBasePrefabs(PrefabsType prefabsType)
        {
            GameObject Prefabs = GameObject.Instantiate(PrefabsManager.Instance.GetPrefabs(prefabsType), PrefabsFa.transform);
            return Prefabs.GetComponent<BasePrefabs>();
        }
        /// <summary>
        /// 重置对象（不是销毁）
        /// </summary>
        /// <param name="basePrefabs"></param>
        void RecycleBasePrefabs(BasePrefabs basePrefabs)
        {
            basePrefabs.OnRecycle();
        }
      
     
    }

    public class PrefabsManager : Singleton<PrefabsManager>
    {
        private ResLoader resLoader = new ResLoader();
        private  Dictionary<PrefabsType, PrefabsCreate> PrefabsCreateDict;//预制体创建类
        private static Dictionary<PrefabsType, string> PrefabsPathDict;//存储预制件路径
        /// <summary>
        /// 增加预制体
        /// </summary>
        /// <param name="prefabsInfo">预制体信息表</param>
        /// <param name="Fa">预制体父级</param>
        /// <param name="isUI">是否是UI</param>
        public  void AddPrefabs(List<PrefabsInfo> prefabsInfo, Transform Fa)
        {
            foreach (var item in prefabsInfo)
            {
                AddPrefabs(item, Fa);
            }
        }
        /// <summary>
        /// 增加预制体
        /// </summary>
        /// <param name="prefabsInfo">预制体信息</param>
        /// <param name="Fa">预制体父级</param>
        /// <param name="isUI">是否是UI</param>
        public  void AddPrefabs(PrefabsInfo prefabsInfo, Transform Fa)
        {
            if (PrefabsCreateDict == null)
            {
                PrefabsCreateDict = new Dictionary<PrefabsType, PrefabsCreate>();
            }

            PrefabsCreate _prefabsCreate;
            if (PrefabsCreateDict.ContainsKey(prefabsInfo.PrefabsType))
            {
                _prefabsCreate = PrefabsCreateDict[prefabsInfo.PrefabsType];
            }
            else
            {
                _prefabsCreate = new PrefabsCreate(prefabsInfo.PrefabsType, prefabsInfo.IsUI, Fa);
                PrefabsCreateDict.Add(prefabsInfo.PrefabsType, _prefabsCreate);
            }

            _prefabsCreate.Add(prefabsInfo.PrefabsName, prefabsInfo.PrefabsPos);
        }

        public override void OnBeforeDestroy()
        {
            
        }

        /// <summary>
        /// 清除预制体
        /// </summary>
        /// <param name="prefabsType">预制体类型</param>
        /// <param name="name">清除的预制体名称表</param>
        public  void RemovePrefabs(PrefabsType prefabsType, List<string> name)
        {
            if (PrefabsCreateDict.ContainsKey(prefabsType))
            {
                PrefabsCreate _prefabsCreate = PrefabsCreateDict[prefabsType];
                _prefabsCreate.Remove(name);
            }
        }
        /// <summary>
        /// 清除预制体
        /// </summary>
        /// <param name="prefabsType">预制体类型</param>
        /// <param name="name">清除的预制体名称</param>
        public  void RemovePrefabs(PrefabsType prefabsType, string name)
        {
            if (PrefabsCreateDict.ContainsKey(prefabsType))
            {
                PrefabsCreate _prefabsCreate = PrefabsCreateDict[prefabsType];
                _prefabsCreate.Remove(name);
            }
        }
        /// <summary>
        /// 清除预制体类型
        /// </summary>
        /// <param name="prefabsType">预制体类型</param>
        public  void RemovePrefabs(PrefabsType prefabsType)
        {
            if (PrefabsCreateDict.ContainsKey(prefabsType))
            {
                PrefabsCreate _prefabsCreate = PrefabsCreateDict[prefabsType];
                _prefabsCreate.Remove();
            }
        }
        /// <summary>
        /// 得到预制体objct
        /// </summary>
        /// <param name="uIPanelType"></param>
        /// <returns></returns>
        public GameObject GetPrefabs(PrefabsType PrefabsType)
        {

            if (PrefabsPathDict == null)
            {
                ParseUIPanelTypeJson();
            }
            string path = PrefabsPathDict.TryGat(PrefabsType);
            //GameObject instPanel = (Resources.Load(path)) as GameObject;
            GameObject Prefabs = resLoader.LoadAssetSync<GameObject>(PrefabsType.ToString(), path);

            return Prefabs;
        }
        /// <summary>
        /// 解析预制体信息
        /// </summary>
        void ParseUIPanelTypeJson()
        {
            if (PrefabsPathDict == null)
            {
                PrefabsPathDict = new Dictionary<PrefabsType, string>();
            }
            TextAsset jsonText = Resources.Load<TextAsset>("Config/PrefabsTypeJson");
            JsonData jsonData = JsonMapper.ToObject(jsonText.text);
            int length = jsonData.Count;
            for (int i = 0; i < length; i++)
            {
                PrefabsPath mPrefabs = new PrefabsPath();
                mPrefabs.PrefabsTypeString = jsonData[i]["prefabsType"].ToString();
                mPrefabs.Path = jsonData[i]["path"].ToString();
                PrefabsPathDict.Add(mPrefabs.prefabsType, mPrefabs.Path);
            }
        }
        
    }

    public class PrefabsInfo
    {
        PrefabsType prefabsType;
        string prefabsName;
        Vector3 prefabsPos;
        bool isUI;
        /// <summary>
        /// string类型输入
        /// </summary>
        public string PrefabsTypeString
        {
            get
            {
                return prefabsType.ToString();
            }

            set
            {
                prefabsType = (PrefabsType)Enum.Parse(typeof(PrefabsType), value);
            }
        }
        public PrefabsType PrefabsType
        {
            get
            {
                return prefabsType;
            }

            set
            {
                prefabsType = value;
            }
        }
        public string PrefabsName
        {
            get
            {
                return prefabsName;
            }

            set
            {
                prefabsName = value;
            }
        }

        public Vector3 PrefabsPos
        {
            get
            {
                return prefabsPos;
            }

            set
            {
                prefabsPos = value;
            }
        }

        public bool IsUI
        {
            get
            {
                return isUI;
            }

            set
            {
                isUI = value;
            }
        }
    }

    /// <summary>
    /// 预制体实例继承类
    /// </summary>
    public abstract class BasePrefabs : MonoBehaviourSimplify
    {
        /// <summary>
        /// ui位置
        /// </summary>
        protected Vector3 UIpos;
        /// <summary>
        /// 是否UI
        /// </summary>
        bool bISUI = false;
       // protected bool bISmove = false;
        private void LateUpdate()
        {
            //实时定位计算
            if (bISUI)
            {
                transform.position = Camera.main.WorldToScreenPoint(UIpos);
            }
      
        }

        /// <summary>
        /// 进入
        /// </summary>
        public abstract void OnEnter();
        /// <summary>
        /// 退出
        /// </summary>
        public abstract void OnExit();

        public abstract void OnRecycle();

        public void Show()
        {
            gameObject.SetActive(true);
        }
        public void Hidden()
        {
            gameObject.SetActive(false);
        }
        /// <summary>
        /// 设置名称
        /// </summary>
        /// <param name="name"></param>
        public void SetName(string name)
        {
            gameObject.name = name;
        }
        /// <summary>
        /// 设置模型位置
        /// </summary>
        /// <param name="vector3"></param>
        public  void SetPos(Vector3 vector3)
        {
            gameObject.transform.position = vector3;
        }
        /// <summary>
        /// 设置ui位置
        /// </summary>
        /// <param name="vector3"></param>
        public  void SetUIPos(Vector3 vector3)
        {
            UIpos = vector3;
            bISUI = true;
        }

        public override void OnBeforeDestroy() { }
    }

    [Serializable]
    public class PrefabsPath
    {
        // [NonSerialized]
        public PrefabsType prefabsType;
        private string path;
        public string PrefabsTypeString
        {
            get
            {
                return prefabsType.ToString();
            }
            set
            {
                prefabsType = (PrefabsType)Enum.Parse(typeof(PrefabsType), value);
            }
        }
        public string Path
        {
            get
            {
                return path;
            }

            set
            {
                path = value;
            }
        }
    }
}

